// ObjectSet.h : Declaration of the CObjectSet

#ifndef __OBJECTSET_H_
#define __OBJECTSET_H_

#include "resource.h"       // main symbols

/////////////////////////////////////////////////////////////////////////////
// CObjectSet
class ATL_NO_VTABLE CObjectSet : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CObjectSet, &CLSID_ObjectSet>,
	public ISupportErrorInfo,
	public IDispatchImpl<IObjectSet, &IID_IObjectSet, &LIBID_GPSOBJECTSLib>,
	public IDispatchImpl<IEnumObject, &IID_IEnumObject, &LIBID_GPSOBJECTSLib>,
	public IDispatchImpl<IAddObject, &IID_IAddObject, &LIBID_GPSOBJECTSLib>
{
public:
	CObjectSet()
	{
		m_CurObjIndex = 0;
	}
	~CObjectSet()
	{
	}

DECLARE_REGISTRY_RESOURCEID(IDR_OBJECTSET)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CObjectSet)
	COM_INTERFACE_ENTRY(IObjectSet)
	COM_INTERFACE_ENTRY(ISupportErrorInfo)
	COM_INTERFACE_ENTRY2(IDispatch, IEnumObject)
	COM_INTERFACE_ENTRY(IEnumObject)
	COM_INTERFACE_ENTRY(IAddObject)
END_COM_MAP()

// ISupportsErrorInfo
	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);

	CList<IDispatch*,IDispatch*>m_ObjectList;
	int m_CurObjIndex;
// IObjectSet
public:
	STDMETHOD(Test)();
	STDMETHOD(DismissAll)();
	STDMETHOD(RemoveAll)();
// IEnumObject
	STDMETHOD(First)(VARIANT * obj)
	{
		if (obj == NULL)
			return E_POINTER;
		obj->vt = VT_DISPATCH;
		obj->pdispVal = 0;
		if(m_ObjectList.GetCount()>0)
			obj->pdispVal = m_ObjectList.GetAt(m_ObjectList.FindIndex(0));	
			
		return S_OK;
	}
	STDMETHOD(Next)(VARIANT * obj)
	{
		if (obj == NULL)
			return E_POINTER;
		obj->vt = VT_DISPATCH;
		obj->pdispVal = 0;
		if(m_ObjectList.GetCount()>0 && m_CurObjIndex<m_ObjectList.GetCount())
		{
			obj->pdispVal = m_ObjectList.GetAt(m_ObjectList.FindIndex(m_CurObjIndex++));
		}
		else
			m_CurObjIndex = 0;

		return S_OK;
	}
	STDMETHOD(End)(VARIANT * obj)
	{
		if (obj == NULL)
			return E_POINTER;
		obj->vt = VT_DISPATCH;
		obj->pdispVal = 0;
			
		if(m_ObjectList.GetCount()>0)
			obj->pdispVal = m_ObjectList.GetAt(m_ObjectList.FindIndex(m_ObjectList.GetCount()-1));	
		return S_OK;
	}
	STDMETHOD(ObjFromIndex)(INT Index, VARIANT * obj)
	{
		if (obj == NULL)
			return E_POINTER;
		obj->vt = VT_DISPATCH;
		obj->pdispVal = 0;
		if(Index<0 || Index>=m_ObjectList.GetCount())
			return E_INVALIDARG;

		obj->pdispVal = m_ObjectList.GetAt(m_ObjectList.FindIndex(Index));
		return S_OK;
	}
	STDMETHOD(get_ObjCount)(LONG * pVal)
	{
		if (pVal == NULL)
			return E_POINTER;
			
		*pVal = m_ObjectList.GetCount();
		return S_OK;
	}

// IAddObject
	STDMETHOD(Add)(VARIANT * obj)
	{
		
		if(obj == NULL || obj->vt != VT_DISPATCH || obj->pdispVal == NULL)
			return E_INVALIDARG;
		
		for (int i=0;i<m_ObjectList.GetCount();i++)
		{
			if(	m_ObjectList.GetAt(m_ObjectList.FindIndex(i)) == obj->pdispVal)
				return S_FALSE;
		}
		m_ObjectList.AddTail(obj->pdispVal);
	
		return S_OK;
	}
};

#endif //__OBJECTSET_H_
